package br.com.spam.pipeline.instruction.i;

import java.util.Map;

import br.com.spam.pipeline.core.ControlSignal;
import br.com.spam.pipeline.core.Memory;
import br.com.spam.pipeline.core.Processor;
import br.com.spam.pipeline.instruction.ITypeInstruction;
import br.com.spam.pipeline.instruction.RsRtLoader;
import br.com.spam.pipeline.instruction.r.ADD;

public class SW extends ITypeInstruction
{

	public static final int ID = 101011;
	private Memory memory;
	private int address;
	private RsRtLoader loader;

	public SW(String instruction, Processor processor, Memory memory)
	{
		super(instruction, processor);
		this.memory = memory;
		this.loader = new RsRtLoader(this.rs(), this.rt(), this);
	}

	@Override
	public String getInstructionAsString()
	{
		return String.format("I%d: %s %s %d(%s)", this.index(), this.name(), this.rt().name(), this
				.immediate(), this.rs().name());
	}

	@Override
	protected boolean afterInstructionDecode()
	{
		return this.loader.instructionDecodeHook();
	}

	@Override
	public boolean execute()
	{
		this.loader.executionHook();
		this.address = this.loader.rsValue() + this.immediate();
		return true;
	}

	@Override
	public boolean memory()
	{
		this.memory.store(this.address, this.loader.rtValue());
		return true;
	}

	@Override
	public final void generateControlSignals(Map<ControlSignal, Object> controlSignals)
	{
		controlSignals.put(ControlSignal.ALUSrcB, 1);
		controlSignals.put(ControlSignal.RegWrite, 1);
		controlSignals.put(ControlSignal.MemWrite, 1);
		controlSignals.put(ControlSignal.Branch, 0);
		controlSignals.put(ControlSignal.Jump, 0);
		controlSignals.put(ControlSignal.ALUOp, ADD.ALUOpCode);
	}
}